package pro.cherish.knowledgenotifywebsocket.socket;


import com.fasterxml.jackson.databind.ObjectMapper;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Controller;
import pro.cherish.knowledgenotifywebsocket.cmmon.TransResult;

import javax.servlet.http.HttpSession;
import javax.websocket.*;
import javax.websocket.server.ServerEndpoint;
import java.io.IOException;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;

/**
 * @author 创建人：cherish
 * @version 版本号：V1.0
 * <p>
 * ***************************修订记录************************************
 * 2019-09-13 cherish 创建该类功能。
 * **********************************************************************
 * </p>
 * @ClassName 类名：ScocketHandler
 * @Description 功能说明：
 * <p>
 * TODO
 * </p>
 * **********************************************************************
 * @date 创建日期： 2019-09-13 cherish
 */

@Controller
@ServerEndpoint(value = "/websocket", configurator = HttpSessionConfigurator.class)
@Slf4j
public class ScocketHandler {

    /*websocket 客户端会话 通过Session 向客户端发送数据*/
    private Session session;

    /*存活的session集合（使用线程安全的map保存）*/
    private static Map<Long, ScocketHandler> sessionManger = new ConcurrentHashMap<Long, ScocketHandler>();

    /*websocket 连接建立成功后进行调用*/
    @OnOpen
    public void onOpen(Session session, EndpointConfig config) {
        this.session = session;
        HttpSession httpSession = (HttpSession) config.getUserProperties().get(HttpSession.class.getName());
        Long userId = (Long) httpSession.getAttribute("userId");
        sessionManger.put(userId, this);
        System.out.println("websocket有新的链接" + sessionManger.size());
    }

    /*websocket 链接关闭调用的方法*/
    @OnClose
    public void onClose() {
        sessionManger.remove(this);
    }

    /*收到客户端消息后调用的方法*/
    @OnMessage
    public void onMessage(String message) throws IOException {
    }

    /*websocket 发生错误时进行调用*/
    @OnError
    public void onError(Session session, Throwable error) {
        error.printStackTrace();
    }

    /**
     * @Description: 推送给所有的用户
     * @Param: [message]
     * @return: void
     * @Author: cherish
     * @Date: 2019/9/13
     */
    public static void sendAll(String message) throws IOException {
        for (Map.Entry<Long, ScocketHandler> entry : sessionManger.entrySet()) {
            Session session = entry.getValue().session;
            session.getBasicRemote().sendText("" + message);
        }
    }

    /**
     * @Description: 发送信息给指定ID用户，如果用户不在线则返回不在线信息给自己
     * @Param: [message, toUserId]
     * @return: void
     * @Author: cherish
     * @Date: 2019/9/13
     */
    public static void sendtoUser(TransResult result, Long toUserId) throws IOException {
        Session session = sessionManger.get(toUserId).session;
        if (session != null) {
            ObjectMapper mapper = new ObjectMapper();
            session.getBasicRemote().sendText(mapper.writeValueAsString(result));
        } else {
            log.info("用户不在线,推送到用户的代办导出任务");
        }
    }

    public Session getSession() {
        return session;
    }

    public void setSession(Session session) {
        this.session = session;
    }
}
